import { ContextItem } from './LingmaContext';
import { LingmaSDKTool } from './LingmaSDKTool';

/**
 * 灵码编程助手前置处理接口
 * @param request 用户发送的请求
 * @param SDKTool SDK工具类，通过该工具类可以获取与IDE、Plugin相关的信息
 * @returns 经过前置处理处理后的返回结果
 */
export interface RequestPreHandler {
  // 前置处理方法
  handle: (request: RawRequest, SDKTool: LingmaSDKTool) => Promise<PreHandlerResponse>;
}

/**
 * 灵码编程助手后置处理接口
 * @param request 用户发送的请求
 * @param response LLM返回的推理内容
 * @param SDKTool SDK工具类，通过该工具类可以获取与IDE、Plugin相关的信息
 * @returns 经过后置处理器处理后的返回结果
 */
export interface RequestPostHandler {
  // 后置处理方法
  handle: (request: RawRequest, response: AIResponse, SDKTool: LingmaSDKTool) => Promise<PostHandlerResponse>;
}


/**
 * 请求对象定义，请求包括触发的行为和待发送给LLM的原始数据
 */
export interface RawRequest {
  // 当前请求唯一标识，可用于追踪请求执行
  action: ActionEnum;
  // 触发请求的行为枚举
  payload: ContentPayload;
  // 封装原始数据内容的payload
  requestId: string;
}

/**
 * 前置处理结果
 */
export class PreHandlerResponse {
  // 处理策略，通过该策略可以控制后续的处理逻辑
  handlePolicy: HandlePolicy;
  // 原因描述
  reason?: string;
  // 当handlePolicy=FILTER时，需要设置该属性，其值为经过过滤后的数据（必须与ContentRequest.payload的内容保持一致）
  payload?: ContentPayload;
  constructor() {
    // 默认值
    // eslint-disable-next-line @typescript-eslint/no-use-before-define
    this.handlePolicy = HandlePolicy.NO_OPS;
    this.reason = '';
    this.payload = new ContentPayload();
  }
}

/**
 * 预处理结果
 */
export class PostHandlerResponse {
  // 处理策略，通过该策略可以控制后续的处理逻辑
  handlePolicy: HandlePolicy;
  // 原因描述
  reason?: string;
  // 经过后置处理器处理过的模型返回结果
  processedResult: InferredResult;
  constructor() {
    // 默认值
    this.handlePolicy = HandlePolicy.NO_OPS;
    this.reason = '';
    this.processedResult = new InferredResult();
  }
}

/**
 * 封装大模型返回结果
 */
export class AIResponse {
  // 模型推理结果
  inferredResult: InferredResult;
  constructor() {
    this.inferredResult = new InferredResult();
  }
}

/**
 * 模型推理生成的结果数据
 */
export class InferredResult {
  // LLM生成的文本内容
  text: string;
  constructor() {
    this.text = '';
  }
}
/**
 * 封装发送给LLM的原始数据内容
 */
export class ContentPayload {
  // 待处理的数据集合，对应的key参考ContextValueKeyEnum定义
  data: Map<PayloadDataKeyEnum, PayloadDataValueType>;
  // 与处理关联的上下文
  associatedContexts: ContextItem[];

  constructor() {
    this.data = new Map<PayloadDataKeyEnum, PayloadDataValueType>();
    this.associatedContexts = [];
  }
}


/**
 * ContentPayload.data 中key枚举
 */
export enum PayloadDataKeyEnum {
  // 用户圈选的代码片段
  SELECTED_CODE ='lingma:code',
  // 用户输入的文本
  USER_INPUT = 'lingma:text',
  // 报错信息
  ERROR_MESSAGES = 'lingma:error_messages',
  // 终端打印的日志信息
  TERMINAL_CONTENT = 'lingma:terminal_content',
  // 代码补全时，当前光标所在行的前文代码片段
  PREFIX_CODE = 'lingma:code_prefix',
  // 代码补全时，当前光标所在行的后文代码片段
  SUFFIX_CODE = 'lingma:code_suffix',
  // 相似代码片段
  SIMILAR_CODE = 'lingma:similar_code',
  // 补全场景执行补全的文件路径
  FILE_PATH = 'lingma:file_path',
}
// ContentPayload.data 中value类型
export type PayloadDataValueType = string | number | string[];

/**
 * 触发请求的行为枚举
 */
export enum ActionEnum {
  // 单元测试
  GENERATE_TESTCASE = 'GENERATE_TESTCASE',
  // 生成注释
  CODE_GENERATE_COMMENT = 'CODE_GENERATE_COMMENT',
  // 代码解释
  EXPLAIN_CODE = 'EXPLAIN_CODE',
  // 代码优化
  OPTIMIZE_CODE = 'OPTIMIZE_CODE',
  // 自由问答（即在问答输入框中直接输入文本的行为）
  FREE_INPUT = 'FREE_INPUT',
  // 代码问题快捷修复
  CODE_PROBLEM_SOLVE = 'CODE_PROBLEM_SOLVE',
  // shell命令生成
  TERMINAL_COMMAND_GENERATION = 'TERMINAL_COMMAND_GENERATION',
  // 终端报错修复
  TERMINAL_EXPLAIN_FIX = 'TERMINAL_EXPLAIN_FIX',
  // 代码补全
  COMPLETION = 'COMPLETION',
}

/**
 * 处理策略枚举
 */
export enum HandlePolicy {
  // 阻断策略，直接阻断请求
  BLOCK = 'BLOCK',
  // 过滤策略，拦截请求并对payload内容进行修改
  FILTER = 'FILTER',
  // 忽略策略，不处理请求
  NO_OPS = 'NO_OPS',
}
